﻿using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Linq;

using Csla;
using Csla.Core;
using Csla.Security;

using Haushaltsbuch.DataAcces;
using Haushaltsbuch.DataAcces.Entities;
using Haushaltsbuch.Helpers;

namespace Haushaltsbuch.Domain.Authentication
{
    [Serializable]
    public class HaushaltsbuchIdentity : CslaIdentityBase<HaushaltsbuchIdentity>
    {
        private static readonly PropertyInfo<string> FullnameProperty =
            RegisterProperty<string>(o => o.Fullname);

        public string Fullname
        {
            get { return this.GetProperty(FullnameProperty); }
            protected set { this.LoadProperty(FullnameProperty, value); }
        }


        #region Factory Methods

        public static HaushaltsbuchIdentity Get(string username, string password)
        {
            return DataPortal.FetchChild<HaushaltsbuchIdentity>(new UsernameCriteria(username, password));
        }

        public static HaushaltsbuchIdentity Get(string username)
        {
            return DataPortal.FetchChild<HaushaltsbuchIdentity>(username);
        }

        #endregion

        private void LoadUserData(User user)
        {
            this.IsAuthenticated = true;
            this.Name = user.Username;
            this.Roles = new MobileList<string>(user.Roles.Select(r => r.Name));
            this.Fullname = user.Fullname;
        }

        #region Data Access

        private void Child_Fetch(UsernameCriteria usernameCriteria)
        {
            this.AuthenticationType = "Custom";
            using (var ctx = new HaushaltsbuchContext())
            {
                var user = ctx.Users.Include(u => u.Roles).SingleOrDefault(u => u.Username == usernameCriteria.Username);
                if (user == null) return;

                var bytes = PasswordHelper.GetHash(usernameCriteria.Password);
                if (bytes.SequenceEqual(user.Passwort))
                    this.LoadUserData(user);
            }
        }

        private void Child_Fetch(string username)
        {
            this.AuthenticationType = "Custom";
            using (var ctx = new HaushaltsbuchContext())
            {
                var user = ctx.Users
                              .Include(u => u.Roles)
                              .SingleOrDefault(u => u.Username == username);
                if (user == null) 
                    return;

                this.LoadUserData(user);
            }
        }

        #endregion
    }
}